﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Shapes;
using System.Windows;
using System.Windows.Media;
using System.Windows.Input;
using System.Windows.Controls;

namespace UmlControlLibrary
{
    public class MoveableRectangle : Shape
    {
        private bool isDragging;
        private Point controlPoint, mousePoint, newMousePoint;

        private List<ConnectionLine> m_ConnectionLineCollection;

        public List<ConnectionLine> ConnectionLineCollection
        {
            get { return m_ConnectionLineCollection; }
            set { m_ConnectionLineCollection = value; }
        }


        public MoveableRectangle()
        {
            this.m_ConnectionLineCollection = new List<ConnectionLine>();
            LinearGradientBrush b = new LinearGradientBrush();
            b.Opacity = 0.3;
            b.StartPoint = new Point (0,0);
            b.EndPoint = new Point (0,0);
            b.GradientStops.Add(new GradientStop(Colors.Red,0));
            b.GradientStops.Add(new GradientStop(Colors.Blue,1));
            this.Fill = b;
        }

        /// <summary>
        /// Propriété utilisée pour indiquer quelle type de forme sera affichée.
        /// </summary>
        protected override Geometry DefiningGeometry
        {
            get 
            {
                RectangleGeometry boxGeometry = new RectangleGeometry(new Rect(new Size(this.Width, this.Height)));
                boxGeometry.RadiusX = 5;
                boxGeometry.RadiusY = 5;

                RectangleGeometry shadowGeometry = boxGeometry.Clone();
                shadowGeometry.Transform = new TranslateTransform(3,3);

                GeometryGroup shadowedBox = new GeometryGroup();
                shadowedBox.Children.Add(boxGeometry);
                shadowedBox.Children.Add(shadowGeometry);
/*                myGeometry.
                RectangleGeometry myGeometry = new RectangleGeometry(new Rect(new Size(this.Width, this.Height)));
                myGeometry.RadiusX = 5;
                myGeometry.RadiusY = 5;*/
                return shadowedBox;
            }
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);

            isDragging = true;

            controlPoint = new Point(Canvas.GetLeft(this), Canvas.GetTop(this));
            mousePoint = new Point(Mouse.GetPosition((IInputElement)this.Parent).X, Mouse.GetPosition((IInputElement)this.Parent).Y);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);

            if (isDragging == true)
            {
                newMousePoint = new Point(Mouse.GetPosition((IInputElement)this.Parent).X, Mouse.GetPosition((IInputElement)this.Parent).Y);

                Canvas.SetLeft(this, (controlPoint.X + newMousePoint.X - mousePoint.X));
                Canvas.SetTop(this, (controlPoint.Y + newMousePoint.Y - mousePoint.Y));

                foreach (ConnectionLine line in this.m_ConnectionLineCollection)
                {
                    switch (line.ConnectionLineDirection)
                    {
                        case ConnectionLine.LineDirection.Start:
                            line.ConnectedLine.X1 = Canvas.GetLeft(this);
                            line.ConnectedLine.Y1 = Canvas.GetTop(this);
                            break;

                        case ConnectionLine.LineDirection.End:
                            line.ConnectedLine.X2 = Canvas.GetLeft(this);
                            line.ConnectedLine.Y2 = Canvas.GetTop(this);
                            break;

                        default:
                            break;
                    }
                }
            }
        }

        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            base.OnMouseUp(e);

            isDragging = false;
        }
    }

    public class ConnectionLine
    {
        public enum LineDirection
        {
            Start,
            End
        }

        private Line m_connectedLine;
        public Line ConnectedLine
        {
            get { return m_connectedLine; }
            set { m_connectedLine = value; }
        }	

        private LineDirection m_lineDirection;
        public LineDirection ConnectionLineDirection
        {
            get { return m_lineDirection; }
            set { m_lineDirection = value; }
        }

        public ConnectionLine(Line line, LineDirection direction)
        {
            this.m_connectedLine = line;
            this.m_lineDirection = direction;
        }
    }
}
